﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using Microsoft.Practices.Composite.Events;
using Microsoft.Practices.Unity;
using Microsoft.Practices.Composite.Presentation.Commands;
using XbdSoft.Domain;
using XbdSoft.Contract;
using XbdSoft.Client;
using System.Windows.Input;
using System.Windows.Media;
using XbdSoft.WPFVersion.Common;

namespace XbdSoft.WPFVersion.ViewModel
{
    public class SearchResourceViewModel : INotifyPropertyChanged
    {
        private const int PageSize = 6;
        private const int DefaultAudioClassID = 151;

        #region Fields 
        protected readonly IEventAggregator EventAggregator = null;
        protected readonly IUnityContainer Container = null;
        protected MediaPlayer mediaPlayer = null;
        #endregion

        #region Ctor

        public SearchResourceViewModel(IEventAggregator eventAggregator, IUnityContainer container)
        {
            EventAggregator = eventAggregator;
            Container = container;

            mediaPlayer = new MediaPlayer();
            TryListenCommand = new DelegateCommand<object>(OnTryListen, o => true);

            SearchCommand = new DelegateCommand<object>(OnSearch);
            NextPageCommand = new DelegateCommand<object>(OnNextPage, o => {
                return HasNextPage();                
            });
            PrePageCommand = new DelegateCommand<object>(OnPrePage, o => { return HasPrePage(); });
            GoPageCommand = new DelegateCommand<object>(OnGoPage, o => true);

            DownloadAllSelectedResourceCommand = new DelegateCommand<object>(OnDownloadAllSelectedResource, o => true);
            SelectAllResourceCommand = new DelegateCommand<object>(OnSelectAllResource, o => true);
            SelectOthersResourceCommand = new DelegateCommand<object>(OnSelectOthersResource, o => true);
            AudioClasses = new List<AudioClass>();
            AllAges = new List<dynamic>() { 
                new{Text="所有年龄段",Value=0},
                new{Text="胎儿",Value=1},
                new{Text="新生儿",Value=2},
                new{Text="0-1岁",Value=3},
                new{Text="1-2岁",Value=4},
                new{Text="2-3岁",Value=5},
                new{Text="3-4岁",Value=6},
                new{Text="4-6岁",Value=7},
                new{Text="6岁以上",Value=8}            
            };
            //Refresh(); 
        }

        public void Refresh()
        {
            try
            {
                using (var service = new ServiceObject<IDownloadService>(Util.DownloadServiceAddress))
                { 
                    AudioClasses = service.Object.GetToShowAudioClasses();
                    SelectedAudioClassIndex = AudioClasses.Count > 0 ? 0 : -1;
                }
            }
            catch { }

            currentPageIndex = 1;
            RefreshResources(); 
        }

        private void RefreshResources()
        {
            try
            {
                using (var service = new ServiceObject<IDownloadService>(Util.DownloadServiceAddress))
                {
                    var audioClass = AudioClasses.Count > 0 && SelectedAudioClassIndex >= 0 ? AudioClasses[SelectedAudioClassIndex] : null;
                    var audioClassID = audioClass != null ? audioClass.ID : DefaultAudioClassID;
                    var age =(int) (SelectedAgeIndex >= 0 ? AllAges[SelectedAgeIndex].Value : 0);
                    var dto = service.Object.GetToShowAudioResources(KeyWord,audioClassID,age, CurrentPageIndex - 1, PageSize);
                    AudioResources = dto.AudioResources;
                    TotalCount = dto.TotalCount;
                }
            }
            catch 
            {
                AudioResources = new List<AudioResource>();
                TotalCount = 0;
            }
            (PrePageCommand as DelegateCommand<object>).RaiseCanExecuteChanged();
            (NextPageCommand as DelegateCommand<object>).RaiseCanExecuteChanged();
        }

        #endregion

        #region Properties

        private List<AudioClass> audioClasses = new List<AudioClass>();
        public List<AudioClass> AudioClasses
        {
            get { return audioClasses; }
            set {
                audioClasses = value;
                OnPropertyChanged("AudioClasses");
            }
        }

        private int selectedAudioClassIndex = 0;
        public int SelectedAudioClassIndex
        {
            get { return selectedAudioClassIndex; }
            set {
                selectedAudioClassIndex = value;
                OnPropertyChanged("SelectedAudioClassIndex");
                currentPageIndex = 1;
                RefreshResources();

            }
        }

        private List<AudioResource> audioResources;
        public List<AudioResource> AudioResources
        {
            get { return audioResources; }
            set {
                audioResources = value;
                OnPropertyChanged("AudioResources");
            }
        }

        private int totalCount = 0;
        public int TotalCount
        {
            get { return totalCount; }
            set {
                totalCount = value;
                OnPropertyChanged("TotalCount");
                OnPropertyChanged("TotalPageCount");
            }
        }

        public int TotalPageCount
        {
            get
            {
                return TotalCount / PageSize + ((TotalCount % PageSize) > 0 ? 1 : 0);
            }
        }

        private int currentPageIndex = 1; // Minium is 1
        public int CurrentPageIndex
        {
            get { return currentPageIndex; }
            set {
                currentPageIndex = value;
                OnPropertyChanged("CurrentPageIndex");
                RefreshResources();
            }
        }

        private string keyWord = string.Empty;
        public string KeyWord
        {
            get { return keyWord; }
            set {
                keyWord = value;
                OnPropertyChanged("KeyWord");
                currentPageIndex = 1;
                selectedAudioClassIndex = -1;
                RefreshResources();
            }
        }

        public void SetKeyWord(string kw)
        {
            keyWord = kw;
        }

        private List<dynamic> allAges = new List<dynamic>();
        public List<dynamic> AllAges
        {
            get { return allAges; }
            set
            {
                allAges = value;
                OnPropertyChanged("AllAges");
            }
        }
        private int selectedAgeIndex = 0;
        public int SelectedAgeIndex
        {
            get { return selectedAgeIndex; }
            set {
                selectedAgeIndex = value;
                OnPropertyChanged("SelectedAgeIndex");
                RefreshResources();
                //SelectedAgeChanged(allAges[value].Value);
            }
        }


        #endregion

        #region INotifyPropertyChanged Members

        protected virtual void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
        public event PropertyChangedEventHandler PropertyChanged;

        #endregion

        #region Command
        public ICommand SearchCommand { get; set; }
        protected void OnSearch(object args)
        {
            KeyWord = (args ?? string.Empty).ToString().Trim();
        }

        public ICommand NextPageCommand { get; set; }
        protected void OnNextPage(object args)
        {
            if (CurrentPageIndex < TotalPageCount)
            {
                CurrentPageIndex++;
                (PrePageCommand as DelegateCommand<object>).RaiseCanExecuteChanged();
                (NextPageCommand as DelegateCommand<object>).RaiseCanExecuteChanged();
            }
        }

        public ICommand PrePageCommand { get; set; }
        protected void OnPrePage(object args)
        {
            if (CurrentPageIndex > 1)
            {
                CurrentPageIndex--;
                (PrePageCommand as DelegateCommand<object>).RaiseCanExecuteChanged();
                (NextPageCommand as DelegateCommand<object>).RaiseCanExecuteChanged();
            }
        }

        public ICommand TryListenCommand { get; set; }
        protected virtual void OnTryListen(object args)
        {
            var id = (int)args;
            try
            {
                var resource = AudioResources.SingleOrDefault(r => r.ID == id);
                if (resource != null)
                {  
                    EventAggregator.GetEvent<TryListenEvent>().Publish(new TryListenEventArgs() { ResourceID = id });
                }
            }
            catch
            {
                mediaPlayer.Close();
            }
        }

        public ICommand GoPageCommand { get; set; }
        protected virtual void OnGoPage(object args)
        {
            var pageIndexStr = (args ?? "1").ToString();
            var pageIndex = CurrentPageIndex;
            if (!Int32.TryParse(pageIndexStr,out pageIndex))
            {
                pageIndex = currentPageIndex;
            }
            CurrentPageIndex = pageIndex;
            (PrePageCommand as DelegateCommand<object>).RaiseCanExecuteChanged();
            (NextPageCommand as DelegateCommand<object>).RaiseCanExecuteChanged();
        }

        public ICommand DownloadAllSelectedResourceCommand { get; set; }
        protected virtual void OnDownloadAllSelectedResource(object args)
        {
            foreach (var resouce in AudioResources)
            {
                if (resouce.Selected)
                {
                    var eventArgs = new DownloadResourceEventArgs() { Resource = resouce };
                    EventAggregator.GetEvent<DownloadResourceEvent>().Publish(eventArgs);
                    //Thread.Sleep(500);
                }
            }
        }

        public ICommand SelectAllResourceCommand { get; set; }
        protected virtual void OnSelectAllResource(object args)
        {
            var isChecked = (bool)args;
            foreach (var resouce in AudioResources)
            {
                resouce.Selected = isChecked;
            }
            OnPropertyChanged("SelectedCategory");
        }

        public ICommand SelectOthersResourceCommand { get; set; }
        protected virtual void OnSelectOthersResource(object args)
        {
            foreach (var resouce in AudioResources)
            {
                resouce.Selected = !resouce.Selected;
            }
            OnPropertyChanged("SelectedCategory");
        }
        #endregion

        #region Age Changed

        protected void SelectedAgeChanged(int ageValue)
        { 
            try
            {
                using (var service = new ServiceObject<IDownloadService>(Util.DownloadServiceAddress))
                {
                    var dto = service.Object.GetToShowAudioResourcesByAge(ageValue, 0, PageSize);
                    AudioResources = dto.AudioResources;
                    TotalCount = dto.TotalCount;
                }
            }
            catch
            {
                AudioResources = new List<AudioResource>();
                TotalCount = 0;
            }
            (PrePageCommand as DelegateCommand<object>).RaiseCanExecuteChanged();
            (NextPageCommand as DelegateCommand<object>).RaiseCanExecuteChanged();
        }

        #endregion

        #region Helper Methods
        private bool HasNextPage()
        {
            return CurrentPageIndex < TotalPageCount;
        }

        private bool HasPrePage()
        {
            return CurrentPageIndex > 1;
        }
        #endregion
    }
}
